﻿#include "myserver.h"
#include "mythread.h"

MyServer::MyServer()
{

}

MyServer::~MyServer()
{
    for(auto iter = m_socketList.begin();iter!=m_socketList.end();++iter)
    {
        if(*iter)
        {
            delete *iter;
            *iter = nullptr;
        }
    }
    for(auto x:m_threadList)
    {
        x->quit();//退出线程
    }
}

void MyServer::incomingConnection(qintptr handle)
{
    MyTcpSocket* socket = new MyTcpSocket;
    socket->setSocketDescriptor(handle);
    m_socketList.append(socket);
    qDebug()<<"have client connected";
    connect(socket,&MyTcpSocket::LogOut,this,&MyServer::deleteSocket);//处理用户登出的槽
    MyThread* thread = new MyThread(socket);
    m_threadList.append(thread);
    thread->start();
}


MyServer &MyServer::getInstance()
{
    static MyServer myServer;
    return myServer;
}

void MyServer::transmitOnline(int msg,MyTcpSocket* sock,userInfo u)
{
    QList<MyTcpSocket*>::iterator iter = m_socketList.begin();
    PDU* pdu = makePDU(0);
    pdu->msgType = msg;
    if(msg == ONLINE)
    {
        for(;iter!=m_socketList.end();iter++)
        {
            if((*iter)!=NULL&&(*iter)!=sock)//向每个人(除此人外)转发此人上线
            {
                (*iter)->write((char*)pdu,pdu->maxSize);
                (*iter)->write((char*)&u,sizeof (u));
                break;
            }

        }

    }
    else if(msg == OFF_ONLINE)
    {
        for(;iter!=m_socketList.end();iter++)//向每个人(除此人外)转发此人下线
        {
            if((*iter)!=NULL)
            {
                (*iter)->write((char*)pdu,pdu->maxSize);
                (*iter)->write((char*)&u,sizeof (u));
                break;
            }
        }
    }
    else if(msg == ADD_FRIEND_S)
    {
        for(;iter!=m_socketList.end();iter++)
        {
            if((*iter)!=NULL&&(0==strcmp(u.name,(*iter)->getUserInfo().toStdString().c_str())))
            {
                //在此处  让u.pwd为被加友好同意了的人的id
                (*iter)->write((char*)pdu,pdu->maxSize);
                MyTcpSocket::getInstance().selectFriend((*iter),u);
            }
            if((*iter)!=NULL&&(0==strcmp(u.pwd,(*iter)->getUserInfo().toStdString().c_str())))
            {
                //在此处  让u.pwd为被加友好的人同意了的id
                (*iter)->write((char*)pdu,pdu->maxSize);
                userInfo temp;
                strcpy(temp.name,u.pwd);//此处的u.pwd是接收者
                //u.name是发送者
                MyTcpSocket::getInstance().selectFriend((*iter),temp);
            }
        }
    }

    else if(msg == FILE_REQUEST)
    {
        for(;iter!=m_socketList.end();iter++)//向接收者发送文件请求
        {
            if((*iter)!=NULL&&(0==strcmp(u.name,(*iter)->getUserInfo().toStdString().c_str())))
            {
                (*iter)->write((char*)pdu,pdu->maxSize);
                (*iter)->write((char*)&u,sizeof (u));
                break;
            }
        }
    }

    else if(msg == FILE_RESPOND_AGREE)//向发送者发送对方已同意接收
    {
        for(;iter!=m_socketList.end();iter++)
        {
            if((*iter)!=NULL&&(0==strcmp(u.pwd,(*iter)->getUserInfo().toStdString().c_str())))
            {
                (*iter)->write((char*)pdu,pdu->maxSize);
                break;
            }
        }
    }

    else if(msg == SEND_MOVE)//向发送者发送抖动信息
    {
        for(;iter!=m_socketList.end();iter++)
        {
            if((*iter)!=NULL&&(0==strcmp(u.name,(*iter)->getUserInfo().toStdString().c_str())))
            {
                (*iter)->write((char*)pdu,pdu->maxSize);
                (*iter)->write((char*)&u,sizeof (u));
                break;
            }
        }
    }

    else if(msg==MEDIA_REQUEST)//向接受者发送视频请求
    {
        for(;iter!=m_socketList.end();iter++)
        {
            if((*iter)!=NULL&&(0==strcmp(u.name,(*iter)->getUserInfo().toStdString().c_str())))
            {
                (*iter)->write((char*)pdu,pdu->maxSize);
                (*iter)->write((char*)&u,sizeof (u));
                break;
            }
        }
    }

    else if(msg==MEDIA_REQUEST_AGREE)//向发送者发送视频请求被同意
    {
        for(;iter!=m_socketList.end();iter++)
        {
            if((*iter)!=NULL&&(0==strcmp(u.pwd,(*iter)->getUserInfo().toStdString().c_str())))
            {
                (*iter)->write((char*)pdu,pdu->maxSize);
                (*iter)->write((char*)&u,sizeof (u));
                break;
            }
        }
    }

    else if(msg==MEDIA_REQUEST_REFUSE)//向发送者发送视频请求被同意
    {
        for(;iter!=m_socketList.end();iter++)
        {
            if((*iter)!=NULL&&(0==strcmp(u.pwd,(*iter)->getUserInfo().toStdString().c_str())))
            {
                (*iter)->write((char*)pdu,pdu->maxSize);
                (*iter)->write((char*)&u,sizeof (u));
                break;
            }
        }
    }
}

void MyServer::transmitOnline(int msg, MyTcpSocket *sock, userInfo u, char* content)//转发消息
{
    QList<MyTcpSocket*>::iterator iter = m_socketList.begin();
    PDU* pdu = makePDU(0);
    pdu->msgType = msg;
    if(msg == MSG_SEND)//收到消息
    {
        for(;iter!=m_socketList.end();iter++)
        {
            if((*iter)!=NULL&&(0==strcmp(u.name,(*iter)->getUserInfo().toStdString().c_str())))
            {
                pdu->msgType=MSG_RECV;
                (*iter)->write((char*)pdu,pdu->maxSize);
                (*iter)->write((char*)&u,sizeof (u));
                (*iter)->write(content,strlen(content)+1);
                return;
            }
        }
        QString filepath = QString("D:\\ChatRecord\\%1.txt").arg(u.name);
        QFile file(filepath);
        if(file.open(QIODevice::Append|QIODevice::WriteOnly))
        {
            QDateTime current_date_time = QDateTime::currentDateTime();
            QString current_date;
            current_date = QString(u.pwd) +"&" + current_date_time.toString("yyyy-MM-dd hh:mm::ss");
            current_date+="\r\n";
            file.write(current_date.toStdString().c_str());
            QString Msg(content);
            Msg = "わ" + Msg + "わ\r\n";
            file.write(Msg.toStdString().c_str());
            file.close();
        }
    }
}

void MyServer::handleAddFriend(const char *name,userInfo src)
{
    QList<MyTcpSocket*>::iterator iter = m_socketList.begin();
    for(;iter!=m_socketList.end();iter++)
    {
        //寻找要加好友的人
        if(0 == strcmp(name,(*iter)->getUserInfo().toStdString().c_str()))
        {
            PDU* pdu =makePDU(0);
            pdu->msgType=ADD_FRIEND;
            (*iter)->write((char*)pdu,pdu->maxSize);
            (*iter)->write((char*)&src,sizeof (src));
            return;
        }
    }
    QString filepath = QString("D:\\ChatRecord\\%1.txt").arg(name);
    QFile file(filepath);
    if(file.open(QIODevice::Append|QIODevice::WriteOnly))
    {
        QDateTime current_date_time = QDateTime::currentDateTime();
        QString current_date;
        current_date = QString(src.name) +"&" + current_date_time.toString("yyyy-MM-dd hh:mm::ss");
        current_date+="\r\n";
        file.write(current_date.toStdString().c_str());
        QString Msg("addFriend");
        Msg = "わ" + Msg + "わ\r\n";
        file.write(Msg.toStdString().c_str());
        file.close();
    }
}

void MyServer::transmitGroupRegS(PDU*& pdu, userInfo u)
{
    for(auto x:m_socketList)
    {
        if(x->getUserInfo()==QString(u.pwd))
        {
            x->write((char*)pdu,pdu->maxSize);
            return;
        }
    }
}

void MyServer::transmitGroupMsg(PDU *&pdu, userInfo u,QString msg, MyTcpSocket *sock)
{
    for(auto x:m_socketList)
    {
        if(x!=sock)
        {
            x->write((char*)pdu,pdu->maxSize);
            x->write((char*)&u,sizeof(u));
            x->write(msg.toUtf8(),msg.toUtf8().length()+1);
        }
    }
}

void MyServer::deleteSocket(MyTcpSocket *sock)
{
    userInfo u;
    QList<MyTcpSocket*>::iterator iter = m_socketList.begin();
    for(;iter!=m_socketList.end();iter++)//找到下线的人  然后记录其名字 再从列表中删除
    {
        if(sock == *iter)
        {
            strcpy(u.name ,(*iter)->getUserInfo().toStdString().c_str());
            m_socketList.erase(iter);
            break;
        }

    }
    iter = m_socketList.begin();
    for(;iter!=m_socketList.end();iter++)//向其他人转发此人下线消息
    {
        if(sock != *iter)
        {
            transmitOnline(OFF_ONLINE,(*iter),u);
            break;
        }
    }
}


